﻿using Bestcode.MathParser;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using iTextSharp.text;
using iTextSharp.text.pdf;


namespace Tubes4_Metnum.Machine
{
    public class Trapesium
    {
        public MathParser parser;
        public bool IsExp;
        public int nVar;
        public double [] a;
        public double [] b;
        public double [] h;
        public int [] n;
        public double[] dataX;
        public double[] dataY;
        public double[] tempRes;
        public double result;
        private bool Xset;
        private bool Yset;

        public Trapesium()
        {
            parser = new MathParser();
            nVar = 1;
            IsExp = false;
            a = new double[2];
            b = new double[2];
            h = new double[2];
            n = new int[2];
            Xset = false;
            Yset = false;
        }

        public void setDataX(double[] data)
        {
            this.dataX = data;
            Xset = true;
        }

        public void setDataY(double[] data)
        {
            this.dataY = data;
            Yset = true;
        }

        public void setExpression(String exp)
        {
            parser.Expression = exp;
            Xset = false; Yset = false;
            Console.WriteLine(exp);
        }

        public double evalX(double X){
            parser.X = X;
            return (double)parser.Value;
        }

        public double evalXY(double X, double Y)
        {
            parser.X = X;
            parser.Y = Y;
            return (double)parser.Value;
        }

        public double integral_data(double[] dX, double[] dY)
        {
            this.result = 0;

            this.dataX = dX; this.dataY = dY;
            this.n[0] = dataX.Length - 1;
            this.a[0] = dataX[0]; this.b[0] = dX[n[0]];
            this.h[0] = (b[0] - a[0]) / n[0];
            for (int i = 0; i < dataY.Length; i++)
            {
                if (dataX[i] == a[0] || dataX[i] == b[0])
                    result += dataY[i];
                else
                    result += 2 * dataY[i];
            }
            result = h[0] * result / 2;
            this.nVar = 1;

            return result;
        }

        public double integral(String exp, double a, double b, int n)
        {
            double result = 0;
            double h = (b - a)/n;
            
            dataX = new double[n+1];
            for (int i = 0; i < dataX.Length; i++)
            {
                dataX[i] = a + h * i;
            }

            parser.Expression = exp;
            dataY = new double[dataX.Length];
            for (int i = 0; i < dataY.Length; i++)
            {
                parser.X = dataX[i];
                dataY[i] = (double) parser.Value;
                if (dataX[i] == a || dataX[i] == b)
                    result += dataY[i];
                else
                    result += 2 * dataY[i];
            }
            result = h * result / 2;
            this.nVar = 1;
            this.a[0] = a;
            this.b[0] = b;
            this.h[0] = h;
            this.n[0] = n;

            this.result = result;
            return result;
        }

        public double integral_ganda(double ax, double bx, double ay, double by, int nx, int ny)
        {
            double result = 0;
            double hx = (bx - ax) / nx;
            double hy = (by - ay) / ny;
            dataX = new double[nx + 1];
            dataY = new double[ny + 1];
            tempRes = new double[nx + 1];
            for (int i = 0; i < dataX.Length; i++)
            {
                dataX[i] = ax + hx * i;
            }
            for (int i = 0; i < dataY.Length; i++)
            {
                dataY[i] = ay + hy * i;
            }

            String ori_exp = parser.Expression;
            for (int i = 0; i < dataX.Length; i++)
            {
                Trapesium temp = new Trapesium();
                String exp = ori_exp.Replace("exp", "eksponen");
                Console.WriteLine("1-" + exp);
                exp = exp.Replace("x", "" + dataX[i]);
                Console.WriteLine("2-" + exp);
                exp = exp.Replace("eksponen", "exp");
                Console.WriteLine("3-" + exp);
                exp = exp.Replace("y", "x");
                tempRes[i] = temp.integral(exp, ax, bx, nx);
            }

            for (int i = 0; i < tempRes.Length; i++)
            {
                if (i == 0|| i == tempRes.Length-1)
                    result += tempRes[i];
                else
                    result += 2 * tempRes[i];
            }
            result = hy * result / 2;

            this.nVar = 2;
            this.a[0] = ax; this.a[1] = ay;
            this.b[0] = bx; this.b[1] = by;
            this.h[0] = hx; this.h[1] = hy;
            this.n[0] = nx; this.n[1] = ny;

            this.result = result;
            return result;
        }

        public void printdataX()
        {
            String output = "";
            for (int i = 0; i < dataX.Length; i++)
            {
                output += dataX[i] + "-";
            }
            output = output.Substring(0, output.Length - 1);
            Console.WriteLine(output);
        }

        public void printdataY()
        {
            String output = "";
            for (int i = 0; i < dataY.Length; i++)
            {
                output += dataY[i] + "-";
            }
            output = output.Substring(0, output.Length - 1);
            Console.WriteLine(output);
        }

        public void saveFile(string filePath)
        {
            Document document = new Document();
            try
            {
                string ext = filePath.Substring(filePath.Length - 4, 4);
                if (ext.CompareTo(".pdf") != 0) filePath += ".pdf";
                PdfWriter.GetInstance(document, new FileStream(filePath, FileMode.Create));
                document.Open();

                /* untuk Trapesium */
                document.Add(new Paragraph("Metode Trapesium"));

                PdfPTable ptable;
                PdfPCell pcell;
                if (this.nVar == 1)
                {
                    document.Add(new Paragraph("a = " + this.a[0] + "; b = " + this.b[0] + "; h = " + this.h[0] + "; n = " + this.n[0]));
                    ptable = new PdfPTable(2);
                    iTextSharp.text.Font arial7 = FontFactory.GetFont("ARIAL", 7);
                    pcell = new PdfPCell(new Phrase(new Chunk("X", arial7)));
                    ptable.AddCell(pcell);
                    pcell = new PdfPCell(new Phrase(new Chunk("Y", arial7)));
                    ptable.AddCell(pcell);
                    for (int rows = 0; rows < this.dataX.Length; rows++)
                    {
                        pcell = new PdfPCell(new Phrase(new Chunk(this.dataX[rows].ToString(), arial7)));
                        ptable.AddCell(pcell);
                        pcell = new PdfPCell(new Phrase(new Chunk(this.dataY[rows].ToString(), arial7)));
                        ptable.AddCell(pcell);
                    }
                }
                else
                {
                    document.Add(new Paragraph("ax = " + this.a[0] + "; bx = " + this.b[0] + "; hx = " + this.h[0] + "; nx = " + this.n[0]));
                    document.Add(new Paragraph("ay = " + this.a[1] + "; by = " + this.b[1] + "; hy = " + this.h[1] + "; ny = " + this.n[1]));
                    ptable = new PdfPTable(3);
                    iTextSharp.text.Font arial7 = FontFactory.GetFont("ARIAL", 7);
                    pcell = new PdfPCell(new Phrase(new Chunk("X", arial7)));
                    ptable.AddCell(pcell);
                    pcell = new PdfPCell(new Phrase(new Chunk("Y", arial7)));
                    ptable.AddCell(pcell);
                    pcell = new PdfPCell(new Phrase(new Chunk("integral arah Y", arial7)));
                    ptable.AddCell(pcell);
                    for (int rows = 0; rows < this.dataX.Length; rows++)
                    {
                        pcell = new PdfPCell(new Phrase(new Chunk(this.dataX[rows].ToString(), arial7)));
                        ptable.AddCell(pcell);
                        pcell = new PdfPCell(new Phrase(new Chunk(this.dataY[rows].ToString(), arial7)));
                        ptable.AddCell(pcell);
                        pcell = new PdfPCell(new Phrase(new Chunk(this.tempRes[rows].ToString(), arial7)));
                        ptable.AddCell(pcell);
                    }
                }
                document.Add(new Paragraph("\n"));
                document.Add(ptable);
                document.Add(new Paragraph("Hasil integral: " + this.result));

            }
            catch (DocumentException de)
            {

            }
            catch (IOException ioe)
            {

            }
            document.Close();
        }
    }
}
